package com.mobisystems.youpark;

import java.io.IOException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Random;
import java.util.Set;

import org.json.JSONException;
import org.json.JSONObject;

import android.app.ActionBar;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.app.ProgressDialog;
import android.app.SearchManager;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Color;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.AnimationUtils;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.SearchView;
import android.widget.TextView;
import android.widget.Toast;

import com.beardedhen.androidbootstrap.FontAwesomeText;
import com.google.android.gms.maps.CameraUpdate;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.GoogleMap.OnCameraChangeListener;
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.CameraPosition;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.LatLngBounds;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import com.mobisystems.youpark.utils.UtilityFunctions;
import com.parse.FindCallback;
import com.parse.ParseACL;
import com.parse.ParseException;
import com.parse.ParseGeoPoint;
import com.parse.ParseInstallation;
import com.parse.ParsePush;
import com.parse.ParseQuery;
import com.parse.ParseUser;
import com.parse.SaveCallback;
import com.parse.SendCallback;

public class MyMap extends Activity implements LocationListener {
	private GoogleMap map;
	private LatLng myPosition, newPosition, searchPosition;
	private UtilityFunctions utilityFunctions = new UtilityFunctions();
	private static final double MAX_SEARCH_DISTANCE = .5;
	private float radius;
	private float lastRadius;

	private TextView tvSwapOption;
	private Button bottomButton;
	private static int parkedCount = 0;

	// Fields for helping process map and location changes
	private final Map<String, Marker> mapMarkers = new HashMap<String, Marker>();
	private int mostRecentMapUpdate = 0;
	private boolean hasSetUpInitialLocation = false;
	private Location lastLocation = null;
	private Location currentLocation = null;

	// Get address variables
	private Geocoder geocoder;
	private List<Address> currentAddress;
	private String address, city, country, zip;

	// Location variables
	private LocationManager locationManager;
	private Location location;
	private Marker marker;
	private double longitude, latitude;
	private ProgressDialog GpsProgressDialog;
	private boolean locationStatus = true;
	
	// Search variables
	private SearchManager searchManager;
	private SearchView searchView;
	private List<Address> Addresses;
	private double searchLongitude, searchLatitude;
	private String query;
	private int searchId;
	private TextView searchTextView;

	// temporary variable for set/unset space
	private boolean spaceSet = false;

	/*
	 * Constants for handling location results
	 */
	// Conversion from feet to meters
	private static final float METERS_PER_FEET = 0.3048f;

	// Initial offset for calculating the map bounds
	private static final double OFFSET_CALCULATION_INIT_DIFF = 1.0;

	// Accuracy for calculating the map bounds
	private static final float OFFSET_CALCULATION_ACCURACY = 0.01f;

	// payment dialog buttons
	private Button btnFiveDollar;
	private Button btnTenDollar;
	private Button btnFifteenDollar;
	private Button btnTwentyDollar;
	private Button btnCustomAmount;
	private Button btnSubmitCustomAmount;
	
	// Search Button
	private Button searchButton;

	private Dialog paymentDialog;
	private Dialog submitCustomAmountDialog;

	@Override
	protected void onCreate(Bundle savedInstanceState) {

		Log.d("MyMapActivity", "Entered the onCreate() of my map.");
		radius = (float) MAX_SEARCH_DISTANCE;
		lastRadius = radius;
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_my_map);
		paymentDialog = new Dialog(MyMap.this);
		submitCustomAmountDialog = new Dialog(MyMap.this);
		submitCustomAmountDialog.setContentView(R.layout.custom_amount_layout);
		paymentDialog.setContentView(R.layout.amount_modal_dialog);
		
		// defining my ids for the buttons
		btnFiveDollar = (Button) paymentDialog.findViewById(R.id.btnMoneyPaid11);
		btnTenDollar = (Button) paymentDialog.findViewById(R.id.btnMoneyPaid12);
		btnFifteenDollar = (Button) paymentDialog.findViewById(R.id.btnMoneyPaid21);
		btnTwentyDollar = (Button) paymentDialog.findViewById(R.id.btnMoneyPaid22);
		btnCustomAmount = (Button) paymentDialog.findViewById(R.id.btnMoneyPaidCustom);
		btnSubmitCustomAmount = (Button) submitCustomAmountDialog.findViewById(R.id.btnSubmitCustomAmount);

		btnSubmitCustomAmount.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {

			}
		});

		btnFiveDollar.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				String btnAmount = btnFiveDollar.getText().toString();
				String amount = btnAmount.replace("$", "").replace(" ", "");
				Intent confirmRequestIntent = new Intent(MyMap.this, RequestActivity.class);
				confirmRequestIntent.putExtra("PaymentAmount", btnAmount);
				sendPushToParkersInAreaQuery(amount);
				startActivity(confirmRequestIntent);
			}
		});

		btnTenDollar.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				String btnAmount = btnFiveDollar.getText().toString();
				String amount = btnAmount.replace("$", "").replace(" ", "");
				Intent confirmRequestIntent = new Intent(MyMap.this, RequestActivity.class);
				confirmRequestIntent.putExtra("PaymentAmount", btnAmount);
				sendPushToParkersInAreaQuery(amount);
				startActivity(confirmRequestIntent);

			}
		});

		btnFifteenDollar.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				String btnAmount = btnFiveDollar.getText().toString();
				String amount = btnAmount.replace("$", "").replace(" ", "");
				Intent confirmRequestIntent = new Intent(MyMap.this, RequestActivity.class);
				confirmRequestIntent.putExtra("PaymentAmount", btnAmount);
				sendPushToParkersInAreaQuery(amount);
				startActivity(confirmRequestIntent);

			}
		});

		btnTwentyDollar.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				String btnAmount = btnFiveDollar.getText().toString();
				String amount = btnAmount.replace("$", "").replace(" ", "");
				Intent confirmRequestIntent = new Intent(MyMap.this, RequestActivity.class);
				confirmRequestIntent.putExtra("PaymentAmount", btnAmount);
				sendPushToParkersInAreaQuery(amount);
				startActivity(confirmRequestIntent);

			}
		});

		btnCustomAmount.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View view) {
				paymentDialog.dismiss();
				submitCustomAmountDialog.setTitle("Enter custom amount.");
				submitCustomAmountDialog.show();

			}
		});
		
		final Animation titleOut = AnimationUtils.loadAnimation(this, R.anim.alpha_out);
		final Animation alphaOut = AnimationUtils.loadAnimation(this, R.anim.alpha_out);
		final Animation alphaIn = AnimationUtils.loadAnimation(this, R.anim.alpha_in);
		titleOut.setAnimationListener(new AnimationListener() {
			@Override
			public void onAnimationRepeat(Animation arg0) {
			}

			@Override
			public void onAnimationStart(Animation arg0) {
			}

			@Override
			public void onAnimationEnd(Animation animation) {
				TextView mTitleTextView = (TextView) findViewById(R.id.title_text);
				swap();
				mTitleTextView.startAnimation(alphaIn);
				findViewById(R.id.bottom_button).startAnimation(alphaIn);
			}
		});
		
		// defining search for the buttons and search view
        searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
        searchView = (SearchView) findViewById(R.id.search_view);
        searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
        searchView.setIconifiedByDefault(false); 
        searchId = searchView.getContext().getResources().getIdentifier("android:id/search_src_text", null, null);
        searchTextView = (TextView) searchView.findViewById(searchId);
        searchTextView.setTextColor(Color.WHITE); 
        
		// defining search button
		searchButton = (Button) findViewById(R.id.find_button);	
		searchButton.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View view) {
				searchMap();
				if (tvSwapOption.getText().toString().equals("Find a Space")) {
					doMapQuery();
				}
			}
		});
        
		try {
			initializeMap();
			map.setMapType(GoogleMap.MAP_TYPE_HYBRID); // sets map type
			map.setMyLocationEnabled(true); // enables location

			moveMapToMyLocation();

			map.setOnCameraChangeListener(new OnCameraChangeListener() {

				@Override
				public void onCameraChange(CameraPosition position) {
					// Add marker if in Set Space Mode
					if ((tvSwapOption.getText().toString().equals("Post Your Space"))&&(bottomButton.getText().toString().equals("I'm Parked Here"))) {
						map.clear();
						marker = map.addMarker(new MarkerOptions().position(position.target).title("Test Marker"));
					}
					if((tvSwapOption.getText().toString().equals("Find a Space"))) {
						map.clear();
						doMapQuery();
					}
				}
			});

			if (Application.APPDEBUG && parkedCount != 0) {
				Log.d(Application.TAG, "Query returned: " + parkedCount);
				Toast.makeText(this, "Query returned: " + parkedCount, Toast.LENGTH_LONG).show();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		ActionBar mActionBar = getActionBar();
		mActionBar.setDisplayShowHomeEnabled(false);
		mActionBar.setDisplayShowTitleEnabled(false);
		LayoutInflater mInflater = LayoutInflater.from(this);

		View mCustomView = mInflater.inflate(R.layout.custom_actionbar, null);
		TextView mTitleTextView = (TextView) mCustomView.findViewById(R.id.title_text);
		mTitleTextView.setText(R.string.find_space);

		FontAwesomeText settingButton = (FontAwesomeText) mCustomView.findViewById(R.id.button_settings);
		settingButton.startRotate(this, true, FontAwesomeText.AnimationSpeed.SLOW);
		settingButton.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View view) {
				Intent settingsIntent = new Intent(MyMap.this, SettingsActivity.class);
				startActivity(settingsIntent);
			}
		});

		ImageButton switchModesButton = (ImageButton) mCustomView.findViewById(R.id.button_switch_modes);
		switchModesButton.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View view) {
				findViewById(R.id.title_text).startAnimation(titleOut);
				findViewById(R.id.bottom_button).startAnimation(alphaOut);
			}
		});

		mActionBar.setCustomView(mCustomView);
		mActionBar.setDisplayShowCustomEnabled(true);

		tvSwapOption = (TextView) findViewById(R.id.title_text);
		bottomButton = (Button) findViewById(R.id.bottom_button);
		bottomButton.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View view) {
				Button bottomButton = (Button) findViewById(R.id.bottom_button);
				// Request all Mode
				if (bottomButton.getText().toString().equals("Request All")) {
					Toast.makeText(getApplicationContext(), "Parking Request Sent", Toast.LENGTH_SHORT).show();
					showPaymentDialog(view, "How much will you pay?");
				}
				// Set Space
				else if (spaceSet == false) {
					newPosition = marker.getPosition();
					latitude = newPosition.latitude;
					longitude = newPosition.longitude;
					location.setLatitude(latitude);
					location.setLongitude(longitude);
					AddLocationToDatabase(location);
					Toast.makeText(getApplicationContext(), "Parking Location Set at" + latitude + longitude,
							Toast.LENGTH_SHORT).show();
					spaceSet = true;
					bottomButton.setText("Remove Parking Location");
				}

				// unsetSpace
				else if (spaceSet == true) {
					Toast.makeText(getApplicationContext(), "Parking Space Removed", Toast.LENGTH_SHORT).show();
					spaceSet = false;
					map.clear();
					map.moveCamera(CameraUpdateFactory.newLatLngZoom(myPosition,17.0f));
					bottomButton.setText(R.string.set_parking);
				}
			}
		});
	}

	private void sendPushToParkersInAreaQuery(String btnAmount) {
		final ParseGeoPoint locationParseGeoPoint = utilityFunctions
				.getGeoPointFromLocation(currentLocation);
		Log.d(Application.TAG, locationParseGeoPoint.toString());
		
		final ParseQuery<ParseInstallation> pushQuery = ParseInstallation.getQuery();
		
		ParseUser currentUser = ParseUser.getCurrentUser();
		
		int amount = Integer.parseInt(btnAmount);
		JSONObject data = new JSONObject();
		String customerId = currentUser.getString("customerId");
		try {
			data.put("objectId", currentUser.getObjectId());
			data.put("alert", currentUser.get("fullName").toString() + " wants your spot! Are you interested?");
			data.put("FullName", currentUser.get("fullName"));
			data.put("currency", "usd");
			data.put("amount", amount);
			
			
			if(customerId != null) {
				data.put("customerId", customerId);
			}
			
			
			Log.d(Application.TAG, "JSON: " + data.toString());
		} catch (JSONException e1) {
			Log.d(Application.TAG, "JSONException: " + e1.getMessage());
		}
		pushQuery.whereWithinMiles("parkedLocation", locationParseGeoPoint, MAX_SEARCH_DISTANCE);
		pushQuery.whereNotEqualTo("user", currentUser);
		pushQuery.whereEqualTo("isParked", true);
		
		
		
		ParsePush parsePush = new ParsePush();
		parsePush.setQuery(pushQuery);
		parsePush.setData(data);
		
		parsePush.sendInBackground(new SendCallback() {
			
			@Override
			public void done(ParseException e) {
				if(e != null) {
					if(Application.APPDEBUG) {
						Toast.makeText(getApplicationContext(), e.getMessage(), Toast.LENGTH_SHORT).show();
					}
				} else {
					if(Application.APPDEBUG) {
						Toast.makeText(getApplicationContext(), "Successful push!", Toast.LENGTH_SHORT).show();
					}
				}
			}
		});	
	}

	// TODO Auto-generated method stub
	// Method that will swap the option either request or set
	public void swap() {
		tvSwapOption = (TextView) findViewById(R.id.title_text);
		bottomButton = (Button) findViewById(R.id.bottom_button);

		// Change To Post Space Mode
		if (tvSwapOption.getText().toString().equals("Find a Space")) {
			// if space is set
			if (spaceSet == true) {
				tvSwapOption.setText(R.string.post_space);
				bottomButton.setText("Remove Parking Location");
				map.clear();
				marker = map.addMarker(new MarkerOptions().position(newPosition).title("Test Marker"));			
			}
			// space is not set
			else {
				tvSwapOption.setText(R.string.post_space);
				bottomButton.setText(R.string.set_parking);
				map.clear();
				// initialize a marker to current location
				marker = map.addMarker(new MarkerOptions().position(myPosition).title("Test Marker"));
			}
		}
		// change to Find Space Mode
		else {
			tvSwapOption.setText(R.string.find_space);
			bottomButton.setText(R.string.request_all);
			map.clear();
			doMapQuery();
		}
	}

	private void doMapQuery() {
		final int myUpdateNumber = ++mostRecentMapUpdate;
		// if current location is null myLocation = lastLocation else myLocation
		// = currentLocation
		Location myLocation = (currentLocation == null) ? lastLocation : currentLocation;
		if (myLocation == null) {
			cleanUpMarkers(new HashSet<String>());
			return;
		}

		final ParseGeoPoint locationParseGeoPoint = utilityFunctions.getGeoPointFromLocation(myLocation);

		final ParseQuery<YouParkParkedLocation> mapQuery = YouParkParkedLocation.getQuery();

		mapQuery.whereWithinMiles("parkedLocation", locationParseGeoPoint, MAX_SEARCH_DISTANCE);
		mapQuery.whereEqualTo("isParked", true);
		mapQuery.whereNotEqualTo("user", ParseUser.getCurrentUser());
		mapQuery.include("user");
		mapQuery.orderByAscending("createdAt");

		mapQuery.findInBackground(new FindCallback<YouParkParkedLocation>() {

			@Override
			public void done(List<YouParkParkedLocation> objects, ParseException e) {
				if (e != null) {
					Toast.makeText(MyMap.this, e.getMessage(), Toast.LENGTH_LONG).show();
				} else {

					Set<String> toKeep = new HashSet<String>();

					for (YouParkParkedLocation parkingLocation : objects) {
						toKeep.add(parkingLocation.getObjectId());

						Marker oldMarker = mapMarkers.get(parkingLocation.getObjectId());

						MarkerOptions markerOptions = new MarkerOptions()
								.position(
										new LatLng(parkingLocation.getLocation().getLatitude(), parkingLocation
												.getLocation().getLongitude()))
								.icon(BitmapDescriptorFactory.fromResource(R.drawable.map_marker)).anchor(0.5f, 1.0f);

						Marker mapMarker = map.addMarker(markerOptions);
						mapMarkers.put(parkingLocation.getObjectId(), mapMarker);
					}
				}
			}
		});
	}

	private void cleanUpMarkers(Set<String> markersToKeep) {

	}

	private void AddLocationToDatabase(Location randomLocationWithinRadius) {
		double longitude = randomLocationWithinRadius.getLongitude();
		double latitude = randomLocationWithinRadius.getLatitude();

		ParseGeoPoint parkedLocation = new ParseGeoPoint();
		ParseInstallation installation = ParseInstallation.getCurrentInstallation();
		YouParkParkedLocation locationData = new YouParkParkedLocation();
		ParseACL acl = new ParseACL();

		acl.setPublicReadAccess(true);

		parkedLocation.setLongitude(longitude);
		parkedLocation.setLatitude(latitude);

		locationData.setACL(acl);
		locationData.setIsParked(true);
		locationData.setLocation(parkedLocation);
		locationData.setUser(ParseUser.getCurrentUser());
		
		installation.put("parkedLocation", parkedLocation);
		installation.put("user", ParseUser.getCurrentUser());
		installation.put("isParked", true);
		AddressModel address = getAddress();
		locationData.setGeoPointAddress(address.getAddress());
		locationData.setCity(address.getCity());
		locationData.setCountry(address.getCountry());
		locationData.setZipCode(address.getZipCode());
		

		installation.saveInBackground();
		locationData.saveInBackground(new SaveCallback() {

			@Override
			public void done(ParseException e) {
				if (e != null) {
					if (Application.APPDEBUG) {
						Log.d(Application.TAG, e.getMessage());
					}
				} else {
					doMapQuery();
				}
			}
		});
	}

	private void updateZoom(LatLng myLatLng) {
		// Get the bounds to zoom to
		LatLngBounds bounds = calculateBoundsWithCenter(myLatLng);
		map.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds, 5));
	}

	/*
	 * Helper method to calculate the offset for the bounds used in map zooming
	 */
	private double calculateLatLngOffset(LatLng myLatLng, boolean bLatOffset) {

		// The return offset, initialized to the default difference
		double latLngOffset = OFFSET_CALCULATION_INIT_DIFF;
		// Set up the desired offset distance in meters
		float desiredOffsetInMeters = radius * METERS_PER_FEET;
		// Variables for the distance calculation
		float[] distance = new float[1];
		boolean foundMax = false;
		double foundMinDiff = 0;
		// Loop through and get the offset
		do {
			// Calculate the distance between the point of interest
			// and the current offset in the latitude or longitude direction
			if (bLatOffset) {
				Location.distanceBetween(myLatLng.latitude, myLatLng.longitude, myLatLng.latitude + latLngOffset,
						myLatLng.longitude, distance);
			} else {
				Location.distanceBetween(myLatLng.latitude, myLatLng.longitude, myLatLng.latitude, myLatLng.longitude
						+ latLngOffset, distance);
			}
			// Compare the current difference with the desired one
			float distanceDiff = distance[0] - desiredOffsetInMeters;
			if (distanceDiff < 0) {
				// Need to catch up to the desired distance
				if (!foundMax) {
					foundMinDiff = latLngOffset;
					// Increase the calculated offset
					latLngOffset *= 2;
				} else {
					double tmp = latLngOffset;
					// Increase the calculated offset, at a slower pace
					latLngOffset += (latLngOffset - foundMinDiff) / 2;
					foundMinDiff = tmp;
				}
			} else {
				// Overshot the desired distance
				// Decrease the calculated offset
				latLngOffset -= (latLngOffset - foundMinDiff) / 2;
				foundMax = true;
			}
		} while (Math.abs(distance[0] - desiredOffsetInMeters) > OFFSET_CALCULATION_ACCURACY);
		return latLngOffset;
	}

	/*
	 * Helper method to calculate the bounds for map zooming
	 */
	public LatLngBounds calculateBoundsWithCenter(LatLng myLatLng) {
		// Create a bounds
		LatLngBounds.Builder builder = LatLngBounds.builder();

		// Calculate east/west points that should to be included
		// in the bounds
		double lngDifference = calculateLatLngOffset(myLatLng, false);
		LatLng east = new LatLng(myLatLng.latitude, myLatLng.longitude + lngDifference);
		builder.include(east);
		LatLng west = new LatLng(myLatLng.latitude, myLatLng.longitude - lngDifference);
		builder.include(west);

		// Calculate north/south points that should to be included
		// in the bounds
		double latDifference = calculateLatLngOffset(myLatLng, true);
		LatLng north = new LatLng(myLatLng.latitude + latDifference, myLatLng.longitude);
		builder.include(north);
		LatLng south = new LatLng(myLatLng.latitude - latDifference, myLatLng.longitude);
		builder.include(south);

		return builder.build();
	}

	// This is a method to test
	private static Location generateRandomCoordinatesFromPosition(double longitude, double latitude, int radius) {
		Log.d("generateRandomCoords", "Generating Random Coords begin");
		Random random = new Random();

		Location newLocation = new Location(LOCATION_SERVICE);

		// Convert radius from meters to degrees
		double radiusInDegrees = radius / 111000f;

		double u = random.nextDouble();
		double v = random.nextDouble();
		double w = radiusInDegrees * Math.sqrt(u);
		double t = 2 * Math.PI * v;
		double x = w * Math.cos(t);
		double y = w * Math.sin(t);

		// Adjust the x-coordinate for the shrinking of the east-west distances
		double new_x = x / Math.cos(latitude);

		double foundLongitude = new_x + longitude;
		double foundLatitude = y + latitude;

		newLocation.setLatitude(foundLatitude);
		newLocation.setLongitude(foundLongitude);

		Log.d("generateRandomCoords", "Generating Random Coords end");
		Log.d("New coords", "Lat: " + foundLatitude + " Lon: " + foundLongitude);
		return newLocation;
	}

	private void deployRandomMarkersWithinAnArea(Location newLocation) {
		double latitude = newLocation.getLatitude();
		double longitude = newLocation.getLongitude();

		Marker marker = map.addMarker(new MarkerOptions()
				.icon(BitmapDescriptorFactory.fromResource(R.drawable.map_marker)).anchor(0.5f, 1.0f)
				.title("Test Marker").snippet("Text").position(new LatLng(latitude, longitude)));
	}

	private void moveMapToMyLocation() {
		locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);

		// check to see if the location service is on
		if (!locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
			locationEnabledDialog();
		} else {
			if (locationStatus == false) {
				GpsProgressDialog.dismiss();
			}

			// if network provider is off use GPS provider
			if (!locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
				locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 2, MyMap.this);
				location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
			} else {
				locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 2, MyMap.this);
				location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
		}

			// display progress dialog while the provider is getting location 
			if (location == null) {
				GpsProgressDialog = ProgressDialog.show(this, "", "Getting location");
				locationStatus = false;
			} else {
				currentLocation = location;
				latitude = location.getLatitude();
				longitude = location.getLongitude();
				myPosition = new LatLng(location.getLatitude(), location.getLongitude());

				CameraPosition cameraPosition = new CameraPosition.Builder().target(myPosition).zoom(17.0f).build();
				CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition);
				((MapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap().moveCamera(cameraUpdate);
			}
		}
	}

	protected void showPaymentDialog(View view, String title) {

		paymentDialog.setTitle(title);
		paymentDialog.show();

	}

	@Override
	protected void onResume() {
		super.onResume();
		initializeMap();
		doMapQuery();
	}

	@Override
	protected void onRestart() {
		super.onRestart();
		initializeMap();
		moveMapToMyLocation();
		doMapQuery();
	}

	private GoogleMap initializeMap() {
		if (map == null) {
			map = ((MapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap();

			// checking if map created successfully or not
			if (map == null) {
				Toast.makeText(getApplicationContext(), "Unable to create map at this time. Sorry!", Toast.LENGTH_LONG)
						.show();
			}
		}

		return map;
	}

	/*
	 * Define a DialogFragment to display the error dialog generated in
	 * showErrorDialog.
	 */
	public static class ErrorDialogFragment extends DialogFragment {
		// Global field to contain the error dialog
		private Dialog mDialog;

		/**
		 * Default constructor. Sets the dialog field to null
		 */
		public ErrorDialogFragment() {
			super();
			mDialog = null;
		}

		/*
		 * Set the dialog to display
		 * 
		 * @param dialog An error dialog
		 */
		public void setDialog(Dialog dialog) {
			mDialog = dialog;
		}

		/*
		 * This method must return a Dialog to the DialogFragment.
		 */
		@Override
		public Dialog onCreateDialog(Bundle savedInstanceState) {
			return mDialog;
		}
	}

	public void locationEnabledDialog() {
		AlertDialog.Builder builder = new AlertDialog.Builder(MyMap.this);
		builder.setTitle("GPS system is off").setMessage("Do you want to turn on GPS")
				.setPositiveButton("Settings", new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int id) {
						startActivity(new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS));
					}
				}).setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int id) {
					}
				});
		builder.show();
	}

	public AddressModel getAddress() {
    	AddressModel addressModel = new AddressModel();
    	
    	geocoder = new Geocoder(this, Locale.getDefault());
    	try {
			currentAddress = geocoder.getFromLocation(latitude, longitude, 1);
		} catch (IOException e) {
			e.printStackTrace();
		}
    	address = currentAddress.get(0).getAddressLine(0);
    	city = currentAddress.get(0).getLocality();
    	country = currentAddress.get(0).getCountryName();
    	zip = currentAddress.get(0).getPostalCode();  	
    	
    	addressModel.setAddress(address);
    	addressModel.setCity(city);
    	addressModel.setCountry(country);
    	addressModel.setZipCode(zip);
    	
    	return addressModel;
    	
    }

	public void searchMap() {
        query = searchView.getQuery().toString();
        if(!TextUtils.isEmpty(query)) {
			geocoder = new Geocoder(this, Locale.getDefault());
			try {
				Addresses = geocoder.getFromLocationName(query, 2);
			} catch (IOException e) {
				e.printStackTrace();
			}		
			searchLongitude = Addresses.get(0).getLongitude();
			searchLatitude = Addresses.get(0).getLatitude();
			currentLocation.setLatitude(searchLatitude);
			currentLocation.setLongitude(searchLongitude);
	        searchPosition = new LatLng(searchLatitude, searchLongitude);
	        map.moveCamera(CameraUpdateFactory.newLatLngZoom(searchPosition,17.0f));
	        map.clear();
        }
        if((tvSwapOption.getText().toString().equals("Post Your Space"))) {
        	marker = map.addMarker(new MarkerOptions().position(searchPosition).title("Test Marker"));
        }
    }
    
	/* LocationListener Methods */
	@Override
	public void onLocationChanged(Location location) {
		// Log.v("latitude/longitude",""+location.getLatitude()+"/"+location.getLongitude());
		if (!locationStatus) {
			GpsProgressDialog.dismiss();
			locationStatus = true;
			moveMapToMyLocation();
		}
		currentLocation = location;
		if (lastLocation != null
				&& utilityFunctions.getGeoPointFromLocation(location).distanceInKilometersTo(
						utilityFunctions.getGeoPointFromLocation(lastLocation)) < 0.01) {
			return;
		}

		lastLocation = location;
		LatLng myLatLng = new LatLng(location.getLatitude(), location.getLongitude());
		if (hasSetUpInitialLocation = false) {
			updateZoom(myLatLng);
			hasSetUpInitialLocation = true;
		}

		doMapQuery();
	}

	@Override
	public void onProviderDisabled(String provider) {

	}

	@Override
	public void onProviderEnabled(String provider) {

	}

	@Override
	public void onStatusChanged(String provider, int Status, Bundle extras) {

	}
	/* End LocationListener Methods */

}
